package com.pactera.jep.service.sys.security.spring.conf;

import java.util.Collection;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.stereotype.Component;

/**
 * 获取请求的URL所需要的权限
 * 
 * @author ghost
 *
 */
@Component
public class UrlFilterInvocationSecurityMetadataSource implements FilterInvocationSecurityMetadataSource {

	private final static Logger logger = LoggerFactory.getLogger(UrlFilterInvocationSecurityMetadataSource.class);

	@Value("${authentication.profile:local}")
	private String authenticationProfile;

	/**
	 * 获取url对应的权限，获取到的权限将会交给{@link UrlAccessDecisionManager#decide(org.springframework.security.core.Authentication, Object, Collection)}方法处理
	 */
	@Override
	public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {
		String requestUrl = ((FilterInvocation) object).getRequestUrl();
		logger.info("用户请求的地址为{}", requestUrl);
		// 对当前的authenticationProfile进行判断处理：
		// 1.
		// 如果是sso登录，那么不对请求进行任何拦截。因为sso验证是做在zuul上的，在sys项目中无法获取到cas验证，只能判断如果能访问到接口说明是已经通过cas验证的
		// 2. 如果没有指定或者是local，那么说明是本地登录，这个时候就需要进行验证处理了
		// extra：在sso的情况下将/requireLogin屏蔽掉
		// 在local的情况下将sso接口屏蔽掉
		if (StringUtils.isBlank(authenticationProfile) || !"sso".equals(authenticationProfile)) {
			// local的情况下将sso接口屏蔽掉
			if (requestUrl.startsWith("/sso")) {
				return SecurityConfig.createList("ROLE_SSO");
			} else {
				// 返回null表示请求的url不需要任何权限就可以访问到
				if ("/requireLogin".equals(requestUrl)) {
					return null;
				}
				// TODO:目前是没有做url跟角色绑定，因此所有url只需要登录即可以请求得到
				return SecurityConfig.createList("ROLE_LOGIN");
			}
		} else {
			// sso登录的情况，将/requireLogin拦截掉
			if ("/requireLogin".equals(requestUrl)) {
				return SecurityConfig.createList("ROLE_LOCAL");
			} else if (requestUrl.startsWith("/sso")) {
				// 给sso专门开一个权限
				return SecurityConfig.createList("ROLE_SSO_CALLBACK");
			} else {
				if (requestUrl.equals("/appConfig/load") || requestUrl.equals("/sync")
						|| requestUrl.startsWith("/user/findCasUser"))
					return null;
				return SecurityConfig.createList("ROLE_SSO");
			}
		}
	}

	@Override
	public Collection<ConfigAttribute> getAllConfigAttributes() {
		return null;
	}

	@Override
	public boolean supports(Class<?> clazz) {
		return FilterInvocation.class.isAssignableFrom(clazz);
	}

}
